package com.sep.team4;



import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.oauth.OAuth;
import net.oauth.OAuth.Parameter;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider;
import net.oauth.client.OAuthClient;
import net.oauth.client.httpclient4.HttpClient4;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.util.Log;
/**
 * Handles authorization using oauth-protocol
 * @author anton
 *
 */
public class OAuthHandler {
	public static final String CALLBACK_URL = "myscheme://twatt";// change in
	// xml:manifest
	private static final String requestTokenURL = "https://rest.hz.nl/RequestToken.ashx";
	private static final String authorizationURL = "https://rest.hz.nl/UserAuthorize.aspx";
	private static final String accessTokenURL = "https://rest.hz.nl/AccessToken.ashx";
	private static final String consumerKey = "Team4";
	private static final String consumerSecret = "6F9537E14ADE46E6BA36C14A1D076512";
	private static final Uri CALLBACK_URI = Uri.parse(CALLBACK_URL);
	private static OAuthAccessor accessor = null;
	private static OAuthClient client = null;
	private static OAuthHandler instance = null;
	private static Activity parent = null;

	protected OAuthHandler() {
		accessor = defaultAccessor();
		client = new OAuthClient(new HttpClient4());
	}

	/**
	 * Class is singleton
	 * 
	 * @return instance of singleton
	 */
	protected static OAuthHandler getInstance() {
		if (instance == null) {
			instance = new OAuthHandler();
		}
		return instance;
	}

	/**
	 * Store parent-info for saving and retrieving settings
	 * 
	 * @param parent1
	 */
	public void setParent(Activity parent1) {
		parent = parent1;
	}

	/**
	 * 
	 * @return authorization-uri to be used by browser
	 */
	public Uri getAuthorizationUri() {
		return Uri.parse(getAuthorizationUrl());
	}

	/**
	 * 
	 * @return authorization-url to be used by browser
	 */
	public String getAuthorizationUrl() {
		return accessor.consumer.serviceProvider.userAuthorizationURL
				+ "?oauth_token=" + accessor.requestToken + "&oauth_callback="
				+ accessor.consumer.callbackURL;
	}

	public OAuthAccessor defaultAccessor() {
		OAuthServiceProvider provider = new OAuthServiceProvider(
				requestTokenURL, authorizationURL, accessTokenURL);
		OAuthConsumer consumer = new OAuthConsumer(CALLBACK_URL, consumerKey,
				consumerSecret, provider);
		OAuthAccessor accessor = new OAuthAccessor(consumer);
		return accessor;
	}

	public String getScheme() {
		return CALLBACK_URI.getScheme();
	}

	/**
	 * invoke Service from server
	 * 
	 * @param uri
	 *            service to be called
	 * @param params
	 *            extra parameters to be sent with call
	 * @return data received by call
	 */
	public String invoke(String uri, ArrayList<Map.Entry<String, String>> params) {
		OAuthMessage omessage = null;
		String message = "";
		try {
			omessage = client.invoke(accessor, "GET",
					uri, params);
			message = omessage.readBodyAsString();
			int index = message.indexOf("Message:");
			message = message.substring(index + 1);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (OAuthException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return message;
	}

	/**
	 * check if accessToken already defined and saved If so, stores saved keys
	 * in accessor-tokens
	 * 
	 * @return true if accessTokens are stored
	 */
	public boolean accessTokenAlreadyDefined() {
		String myAccessToken = parent.getPreferences(Context.MODE_PRIVATE)
				.getString("accessToken", "");
		String myTokenSecret = parent.getPreferences(Context.MODE_PRIVATE)
				.getString("tokenSecret", "");
		boolean accessTokenExists = myTokenSecret.length() > 0;
		if (accessTokenExists) {
			accessor.accessToken = myAccessToken;
			accessor.tokenSecret = myTokenSecret;
		}
		return accessTokenExists;
	}

	/**
	 * Get access-token using constants defined
	 * 
	 * @param uri
	 *            uri returned by server containing token to be exchanged
	 */
	public void getAccessToken(Uri uri) {
		if (accessTokenAlreadyDefined())
			return;
		String verifier = uri.getQueryParameter(OAuth.OAUTH_TOKEN_SECRET);
		List<Parameter> list = new ArrayList<Parameter>();
		list.add(new Parameter("oauth_verifier", verifier));
		try {
			client.getAccessToken(accessor, "GET", list);
			Log.d("test", "AccessToken:" + accessor.accessToken + " || Secret:"
					+ accessor.tokenSecret);
			// Save tokens in SharedPreferences
			Editor e = parent.getPreferences(Context.MODE_PRIVATE).edit();
			e.putString("accessToken", accessor.accessToken);
			e.putString("tokenSecret", accessor.tokenSecret);
			e.commit();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * get request token Starts OAuth authorization process
	 */
	public void getRequestToken() {
		if (accessTokenAlreadyDefined())
			return;
		// List<Parameter> list = new ArrayList<Parameter>();

		List<Parameter> parameters = new ArrayList<OAuth.Parameter>();
		parameters.add(new Parameter("oauth_callback", CALLBACK_URL));
		try {
			client.getRequestToken(accessor, "GET", parameters);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (OAuthException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
	}

}
